using System;
using System.Collections.Generic;
using CLELCore.Assembly.CLELInstructions;

namespace opt.Analysis.Branch
{
	public class BranchOver
	{
		private BranchTable br_table;
		private List<BranchKey> keys;
		private Dictionary<BranchKey,List<BranchKey>> br_over;

		public BranchOver(List<CLELInstruction> code)
		{
			br_table = new BranchTable(code);
			LoadTable(br_table);
		}

		private void LoadTable(BranchTable table)
		{
			if(table != null)
			{
				br_over = new Dictionary<BranchKey,List<BranchKey>>();
				keys = table.GetKeys();
				int i,j,keys_count = keys.Count;
				BranchKey branch1,branch2;
				List<BranchKey> over;
				int from1,from2,to2;
				for(i = 0;i < keys_count;i++)
				{
					branch1 = keys[i];
					over = new List<BranchKey>();
					from1 = table.GetFrom(branch1);
					for(j = 0;j < keys_count;j++)
					{
						branch2 = keys[j];
						from2 = table.GetFrom(branch2);
						to2 = table.GetTo(branch2);
						if((from1 > from2 && from1 <= to2) || (from1 <= from2 && from1 > to2))
						{
							over.Add(branch2);
						}
					}
					br_over.Add(branch1,over);
				}
			}
		}

		public List<BranchKey> GetKeys()
		{
			return new List<BranchKey>(keys);
		}

		public List<BranchKey> GetBranchOvers(BranchKey key)
		{
			return br_over[key];
		}

		public byte GetOpcode(BranchKey key)
		{
			return br_table.GetOpcode(key);
		}

		public int GetOffset(BranchKey key)
		{
			return br_table.GetOffset(key);
		}

		public List<Int32> GetSwitchOffsets(BranchKey key)
		{
			return br_table.GetSwitchOffsets(key);
		}

		public void SetOffset(BranchKey key,int off)
		{
			br_table.SetOffset(key,off);
		}
	}
}
